package com.ruoyi.system.service.impl;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.system.domain.TlDyDoodsDetail;
import com.ruoyi.system.domain.TlDyGoodsVo;
import com.ruoyi.system.service.EsDyGoodsRepository;
import com.ruoyi.system.service.ITlDyGoodsVoService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.*;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.TlDyGoodsMapper;
import com.ruoyi.system.domain.TlDyGoods;
import com.ruoyi.system.service.ITlDyGoodsService;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;

/**
 * 抖音商品Service业务层处理
 *
 * @author ruoyi
 * @date 2023-10-19
 */
@Service
public class TlDyGoodsServiceImpl implements ITlDyGoodsService
{
    @Autowired
    private TlDyGoodsMapper tlDyGoodsMapper;
//    @Autowired
//    private TlDyDoodsDetailMapper tlDyDoodsDetailMapper;
    @Value("${ruoyi.dyAppid}")
    private String  dyAppid;
    @Value("${ruoyi.dySecretKey}")
    private String  dySecretKey;
    @Autowired
    private EsDyGoodsRepository esDyGoodsRepository;
    // 用于自定义复杂查询
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Autowired
    private ITlDyGoodsVoService iTlDyGoodsVoService;


    /**
     * 查询抖音商品
     *
     * @param id 抖音商品主键
     * @return 抖音商品
     */
    @Override
    public TlDyGoods selectTlDyGoodsById(Long id)
    {
        return tlDyGoodsMapper.selectTlDyGoodsById(id);
    }

    /**
     * 查询抖音商品列表
     *
     * @param tlDyGoods 抖音商品
     * @return 抖音商品
     */
    @Override
    public TableDataInfo selectTlDyGoodsList(TlDyGoodsVo tlDyGoods,PageDomain pageDomain)
    {
//        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(TlDyGoods.class);
//        indexOperations.delete();
//        boolean b = indexOperations.create();
//        Document mapping = indexOperations.createMapping();
//        indexOperations.putMapping();
//        List<TlDyGoods> tlDyGoods1 = tlDyGoodsMapper.selectTlDyGoodsList(tlDyGoods);
//        esDyGoodsRepository.deleteAll();
//        esDyGoodsRepository.saveAll(tlDyGoods1);
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        //构建查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //过滤
        if(tlDyGoods.getPriceStart()!=null){
            boolQuery.must(QueryBuilders.rangeQuery("price").gte(tlDyGoods.getPriceStart() * 100d).lte(tlDyGoods.getPriceEnd() * 100d));
        }
        if(tlDyGoods.getPayersStart()!=null){
            boolQuery.must(QueryBuilders.rangeQuery("sales").gte(tlDyGoods.getPayersStart()).lte(tlDyGoods.getPayersEnd()));
        }
        if(tlDyGoods.getCommissionRateStart()!=null){
            boolQuery.must(QueryBuilders.rangeQuery("activityCosRatio").gte(tlDyGoods.getCommissionRateStart()).lte(tlDyGoods.getCommissionRateEnd()));
        }
        if(tlDyGoods.getStockStart()!=null){
            boolQuery.must(QueryBuilders.rangeQuery("productStock").gte(tlDyGoods.getStockStart()).lte(tlDyGoods.getStockEnd()));
        }
        boolQuery.must(QueryBuilders.termQuery("isAssured",tlDyGoods.getIszx()));
        //类目查询
        if(tlDyGoods.getCategoryList()!=null && tlDyGoods.getCategoryList().size()>0){
            boolQuery.must(QueryBuilders.termsQuery("firstCid", tlDyGoods.getCategoryList()));
        }
        //爆款采集
        if(tlDyGoods.getIsbk()!=null && tlDyGoods.getIsbk()==1){
            boolQuery.must(QueryBuilders.rangeQuery("kolNum").gte(50d));
        }
        //排除status 不等于0的
        boolQuery.mustNot(QueryBuilders.termQuery("activityCosRatio", 0));
        boolQuery.must(QueryBuilders.termQuery("status", "0"));
        //排序
        if(StringUtils.isNotBlank(tlDyGoods.getOrderBys())){
            String orderSet = tlDyGoods.getOrderSet();
            queryBuilder.withSort(SortBuilders.fieldSort(tlDyGoods.getOrderBys()).order(orderSet.equals("desc") ? SortOrder.DESC :  SortOrder.ASC));
        }
        //佣金范围  price * (佣金率/100)
        if(tlDyGoods.getCommissionStart()!=null){
            String script = "def ratio = doc['activityCosRatio'].value; " +
                    "params.commissionStart <= doc['price'].value * (ratio / 10000) && doc['price'].value * (ratio / 10000) <= params.commissionEnd";
            Map<String, Object> scriptParams = new HashMap<>();
            scriptParams.put("commissionStart", tlDyGoods.getCommissionStart());
            scriptParams.put("commissionEnd", tlDyGoods.getCommissionEnd());
            Script scriptObject = new Script(ScriptType.INLINE, "painless", script, scriptParams);
            boolQuery.must(QueryBuilders.scriptQuery(scriptObject));
        }
        if(tlDyGoods.getSensitiveWords()!=null && tlDyGoods.getSensitiveWords().size()>0){
            for (String searchString : tlDyGoods.getSensitiveWords()) {
                boolQuery.mustNot(QueryBuilders.queryStringQuery("*" + searchString + "*").field("title"));
            }
        }

        if(tlDyGoods.getTitlesWords()!=null && tlDyGoods.getTitlesWords().size()>0){
            for (String searchString : tlDyGoods.getTitlesWords()) {
                boolQuery.must(QueryBuilders.queryStringQuery("*" + searchString + "*").field("title"));
            }
        }

        queryBuilder.withQuery(boolQuery);
        Pageable pageable = PageRequest.of(pageNum-1, pageSize);
        NativeSearchQuery build = queryBuilder.withPageable(pageable).build();
        build.setTrackTotalHits(true);
        SearchHits<TlDyGoods> search = elasticsearchRestTemplate.search(build, TlDyGoods.class);
        List<TlDyGoods> results = search.stream()
                .map(SearchHit::getContent)
                .collect(Collectors.toList());
        TableDataInfo tableDataInfo = new TableDataInfo();
        tableDataInfo.setRows(results);
        tableDataInfo.setTotal(results.size());
        tableDataInfo.setCode(200);
        //保存采集条件
        return tableDataInfo;
    }

    /**
     * 新增抖音商品
     *
     * @param tlDyGoods 抖音商品
     * @return 结果
     */
    @Override
    public int insertTlDyGoods(TlDyGoods tlDyGoods)
    {
//        tlDyGoods.setCreateTime(DateUtils.getNowDate());
        return tlDyGoodsMapper.insertTlDyGoods(tlDyGoods);
    }

    /**
     * 修改抖音商品
     *
     * @param tlDyGoods 抖音商品
     * @return 结果
     */
    @Override
    public int updateTlDyGoods(TlDyGoods tlDyGoods)
    {
        return tlDyGoodsMapper.updateTlDyGoods(tlDyGoods);
    }

    /**
     * 批量删除抖音商品
     *
     * @param ids 需要删除的抖音商品主键
     * @return 结果
     */
    @Override
    public int deleteTlDyGoodsByIds(Long[] ids)
    {
        return tlDyGoodsMapper.deleteTlDyGoodsByIds(ids);
    }

    /**
     * 删除抖音商品信息
     *
     * @param id 抖音商品主键
     * @return 结果
     */
    @Override
    public int deleteTlDyGoodsById(Long id)
    {
        return tlDyGoodsMapper.deleteTlDyGoodsById(id);
    }

    @Override
    public int dataSync() {
        //获取全部数据
        Integer page = 1;
        while (true){
            String get = HttpUtils.sendGet("http://api.zcxq.cn/open/goods/list/", "app_id=" + dyAppid + "&sec=" + dySecretKey + "&page="+page+"&uptime=20230101");
            JSONObject jsonObject =  JSONObject.parseObject(get);
            String code = jsonObject.getString("code");
            if(!code.equals("200")){
                return 0;
            }
            String data = jsonObject.getString("data");
            //开始解析
            List<TlDyGoods> insertList = new ArrayList<>();
            List<TlDyGoods> updateList = new ArrayList<>();
            List<TlDyDoodsDetail> insertDetailList = new ArrayList<>();
            JSONObject parse1 = JSONObject.parse(data);
            Integer total = parse1.getInteger("total");
            if(total==0){
                return 1;
            }
            String list = parse1.getString("list");
            JSONArray parse = JSONArray.parse(list);
            //oldids
            List<Long> oldIds = new ArrayList<>();
            for(int i=0;i<parse.size();i++){
                Object o = parse.get(i);
                TlDyGoods tlDyGoods = JSONObject.parseObject(o.toString(), TlDyGoods.class);
                oldIds.add(tlDyGoods.getId());
            }
            List<TlDyGoods> oldGoods = tlDyGoodsMapper.selectTlDyGoodsByIds(oldIds);
            Map<Long, List<TlDyGoods>> collect = oldGoods.stream().collect(Collectors.groupingBy(TlDyGoods::getId));
            for(int i=0;i<parse.size();i++){
                Object o = parse.get(i);
                TlDyGoods tlDyGoods = JSONObject.parseObject(o.toString(), TlDyGoods.class);
//                //获取详情数据
//                String detail = HttpUtils.sendPost("https://www.zcxq.com/v1/leya/share/goods/detail/", "product_id=" + tlDyGoods.getProductId());
//                JSONObject detailjsonObject =  JSONObject.parseObject(detail);
//                String detailcode = detailjsonObject.getString("code");
//                if(!detailcode.equals("200")){
//                    continue;
//                }
//                //解析详情
//                String detailData = detailjsonObject.getString("data");
//                TlDyDoodsDetail tlDyDoodsDetail = JSONObject.parseObject(detailData, TlDyDoodsDetail.class);
                List<TlDyGoods> tlDyGoods1 = collect.get(tlDyGoods.getId());
                if(tlDyGoods1!=null){
                    Long upTime = Long.parseLong(tlDyGoods1.get(0).getUpTime());
                    Long upTime1 = Long.parseLong(tlDyGoods.getUpTime());
                    if(upTime<upTime1){
                        //需要更新的列表
                        updateList.add(tlDyGoods);
                    }
                }else {
                    insertList.add(tlDyGoods);
                    //insertDetailList.add(tlDyDoodsDetail);
                }
            }
            if(insertList.size()>0){
                tlDyGoodsMapper.insertTlDyGoodsList(insertList);
            }
            if(updateList.size()>0){
                for (TlDyGoods update:updateList) {
                    tlDyGoodsMapper.updateTlDyGoods(update);
                }
//                tlDyGoodsMapper.updateTlDyGoodsList(updateList);
            }
//            if(insertDetailList.size()>0){
//                tlDyDoodsDetailMapper.insertTlDyDoodsDetailList(insertDetailList);
//            }
            page++;
        }
    }

    @Override
    public int saveES() {
        //将抖音数据同步到es缓存
        Integer pageNum = 1;
        esDyGoodsRepository.deleteAll();
        while (true){
            Integer pageSize = 10000;
            Integer os = ((pageNum - 1) * pageSize);
            List<TlDyGoods> tlDyGoods1 = tlDyGoodsMapper.selectTlDyGoodsListByPage(pageSize,os);
            if(tlDyGoods1!=null && tlDyGoods1.size()>0){
//                for (TlDyGoods tlDyGoods:tlDyGoods1) {
//                    esDyGoodsRepository.save(tlDyGoods);
//                }
                esDyGoodsRepository.saveAll(tlDyGoods1);
                pageNum ++;
            }else {
                return 0;
            }
        }
    }

    @Override
    public void export(HttpServletResponse response, List<String> ids,TlDyGoodsVo tlDyGoodsVo) {
        List<TlDyGoods> tlDyGoods = new ArrayList<>();
        if(ids!=null && ids.size()>0){
            tlDyGoods = esDyGoodsRepository.findByIds(ids);
        }else {
            PageDomain pageDomain = TableSupport.buildPageRequest();
            pageDomain.setPageNum(1);
            pageDomain.setPageSize(10000);
            TableDataInfo tableDataInfo = selectTlDyGoodsList(tlDyGoodsVo,pageDomain);
            tlDyGoods = (List<TlDyGoods>)tableDataInfo.getRows();
            while (tableDataInfo.getTotal() > tlDyGoods.size()) {
                // 继续执行下一页的查询
                pageDomain.setPageNum(pageDomain.getPageNum() + 1);
                TableDataInfo nextPageDataInfo = selectTlDyGoodsList(tlDyGoodsVo, pageDomain);
                List<TlDyGoods> nextPageGoods = (List<TlDyGoods>) nextPageDataInfo.getRows();
                tlDyGoods.addAll(nextPageGoods);
            }
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (TlDyGoods goods : tlDyGoods) {
            String productId = goods.getProductId();
            stringBuilder.append("https://haohuo.jinritemai.com/ecommerce/trade/detail/index.html?id=").append(productId).append("\n");
        }
        String content = stringBuilder.toString();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try (OutputStreamWriter writer = new OutputStreamWriter(outputStream)) {
            writer.write(content);
        }catch (Exception e){
            e.printStackTrace();
        }
        try (OutputStream servletOutputStream = response.getOutputStream()) {
            response.setContentType("text/plain");
            response.setHeader("Content-Disposition", "attachment; filename=\"file.txt\"");
            response.setContentLength(outputStream.size());

            outputStream.writeTo(servletOutputStream);
            outputStream.flush();
            System.out.println("File exported successfully.");
        } catch (IOException e) {
            // 处理异常
        }
    }

    @Override
    public TableDataInfo stopList() {
        //查询没有结束的采集
        SysUser user = SecurityUtils.getLoginUser().getUser();
        TlDyGoodsVo tlDyGoodsVo = iTlDyGoodsVoService.selectByUserIdAndState(user.getUserId(), 0L);
        if(tlDyGoodsVo==null){
            throw new ServiceException("没有采集任务，请开始采集！");
        }
        Date createTime = tlDyGoodsVo.getCreateTime();
        Date newDate = new Date();
        long dfTime = newDate.getTime() - createTime.getTime();
        //开始采集到结束采集的间隔时间
        int seconds = (int) (dfTime / 1000);
        PageDomain pageDomain = new PageDomain();
        pageDomain.setPageNum(1);
        pageDomain.setPageSize(seconds*5);
        //string转list
         if (tlDyGoodsVo.getCategoryListString() != null && !tlDyGoodsVo.getCategoryListString().equals("")) {
             tlDyGoodsVo.setCategoryList(Arrays.stream(tlDyGoodsVo.getCategoryListString().split("#"))
                     .map(Long::parseLong)
                     .collect(Collectors.toList()));
        }
        if(tlDyGoodsVo.getSensitiveWordsString()!=null && !tlDyGoodsVo.getSensitiveWordsString().equals("")){
            tlDyGoodsVo.setSensitiveWords(Arrays.stream(tlDyGoodsVo.getCategoryListString().split("#"))
                    .collect(Collectors.toList()));
        }
        if(tlDyGoodsVo.getTitlesWordsString() !=null && !tlDyGoodsVo.getTitlesWordsString().equals("")){
            tlDyGoodsVo.setTitlesWords(Arrays.stream(tlDyGoodsVo.getTitlesWordsString().split("#"))
                    .collect(Collectors.toList()));
        }
        TableDataInfo tableDataInfo = this.selectTlDyGoodsList(tlDyGoodsVo, pageDomain);
        //结束采集记录
        tlDyGoodsVo.setState(1L);
        tlDyGoodsVo.setEndTime(newDate);
        tlDyGoodsVo.setCjNum(tableDataInfo.getTotal());
        iTlDyGoodsVoService.updateTlDyGoodsVo(tlDyGoodsVo);
        return tableDataInfo;
    }
}
